package com.xd.center.http.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * 动态代理类
 */
public interface HttpHandlerFactory {

  InvocationHandler create(Class c, Map<Method, MethodHandler> dispatch);

  /**
   * 动态代理入口
   */
  class Default implements HttpHandlerFactory {

    @Override
    public InvocationHandler create(Class c, Map<Method, MethodHandler> dispatch) {
      return new DefaultInvocationHandler(c, dispatch);
    }

    /**
     * 为每个方法生成动态代理
     */
    class DefaultInvocationHandler implements InvocationHandler {

      private final Class c;
      private final Map<Method, MethodHandler> dispatch;

      DefaultInvocationHandler(Class c, Map<Method, MethodHandler> dispatch) {
        this.c = c;
        this.dispatch = dispatch;
      }

      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("equals".equals(method.getName())) {
          try {
            Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
            return equals(otherHandler);
          } catch (IllegalArgumentException e) {
            return false;
          }
        } else if ("hashCode".equals(method.getName())) {
          return hashCode();
        } else if ("toString".equals(method.getName())) {
          return toString();
        }
        return dispatch.get(method).invoke(args);
      }

      @Override
      public boolean equals(Object obj) {
        if (obj instanceof DefaultInvocationHandler) {
          DefaultInvocationHandler other = (DefaultInvocationHandler) obj;
          return c.equals(other.c);
        }
        return false;
      }

      @Override
      public int hashCode() {
        return c.hashCode();
      }

      @Override
      public String toString() {
        return c.toString();
      }
    }

  }


}
